/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pe.edu.pucp.Envios.Controlador;

import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import javax.swing.JFileChooser;
import pe.edu.pucp.Envios.DAO.EnviosDAO;
import pe.edu.pucp.Envios.Vista.GenerarEnviosGUI;
import pe.edu.pucp.Envios.Vista.MapaEnvioGUI;
import pe.edu.pucp.Modelo.Ciudad;
import pe.edu.pucp.Modelo.Cliente;
import pe.edu.pucp.Modelo.Continente;
import pe.edu.pucp.Modelo.Envio;
import pe.edu.pucp.Modelo.EstadoEnvio;
import pe.edu.pucp.Modelo.NotaCredito;
import pe.edu.pucp.Modelo.Pago;
import pe.edu.pucp.Modelo.Pais;
import pe.edu.pucp.Modelo.TipoCorreo;
import pe.edu.pucp.Modelo.TipoPago;
import pe.edu.pucp.Modelo.Usuario;
import pe.edu.pucp.Util.Constante;
import pe.edu.pucp.Util.EmailHelper;
import pe.edu.pucp.Util.LogHelper;
import pe.edu.pucp.Util.PdfHelper;
import pe.edu.pucp.Util.Utilitario;
import pe.edu.pucp.Util.ValHelper;
import pe.edu.pucp.Ventas.DAO.ClientesDAO;
import pe.edu.pucp.Ventas.DAO.PagoDAO;
import pe.edu.pucp.sigepa.recocidosimulado.domain.interfaz.Problema;
import pe.edu.pucp.sigepa.recocidosimulado.domain.interfaz.Solucion;
import pe.edu.pucp.sigepa.recocidosimulado.fachada.MotorGeneradorTrayectoriasFachada;
/**
 *
 * @author pachon
 */
public class EnviosControlador {    
    private EnviosDAO m;
    private Envio envio;
    private GenerarEnviosGUI generarView;
    private ArrayList<Continente> lstContinentes;
    private ArrayList<Pais> lstPais;
    private ArrayList<Ciudad> lstCiudades;
    private Usuario user;
    private Cliente cliente;
    private Solucion lstVuelos;
    private PagoDAO dao;
    private ArrayList<TipoPago> lstTipoPago;
    private ArrayList<NotaCredito> lstNotaCredito;
    private ArrayList<TipoCorreo> lstTipoCorreo;
    private String RUTA_DOCUMENTO = "/home";
    
    public EnviosControlador(EnviosDAO dao, GenerarEnviosGUI view, Usuario user, Cliente c){
        this.m = dao;
        this.generarView = view;
        this.user = user;
        this.cliente = c;     
        this.dao = new PagoDAO();
        loadCombos();        
        
        generarView.SetValues(user.getAeropuerto().getCiudad(), cliente);
        generarView.addAbrifFileListener(new AbrirFile());
        generarView.addGenerarButtonListener(new GenerateButtonListener(this));
        generarView.addCambiarContinente(new CambiarLstPaisListener());
        generarView.addCambiarPais(new CambiarLstCiudadListener());
        generarView.addGuardarEnvioButtonListener( new MostrarPagoButtonListener());
        generarView.addCerrarVentanEnvioListener(new CerrarEnvioListener());
        generarView.disableNotacredito();
        generarView.disableTarjeta();
        generarView.addCambiarPago(new EnviosControlador.CambiarLstTipoPagoListener());
        generarView.addSoloTextoListener(new SoloTextoListener());
        generarView.addSoloNumeros(new SoloNumerosListener());
        generarView.addVerRecorrido(new VerRecorrido());
    }
 
    private void loadCombos() {
        llenarContinentes();
        llenarPaises(lstContinentes.get(generarView.getContinente()));
        llenarCiudades(lstPais.get(generarView.getPais())); 
        llenarTipoCorreo();
        llenaTipoPago(); 
    }
    
    public void llenarContinentes(){
        lstContinentes = m.listarContinentes();
        generarView.llenaContinentes(lstContinentes);
    }
    
    public void llenarPaises(Continente continente){
        lstPais = m.listarPaises(continente);
        generarView.llenaPaises(lstPais);
    }
    
    public void llenarCiudades(Pais pais){
        lstCiudades = m.listarCiudades(pais);
        generarView.llenaCiudades(lstCiudades);
    }
    
    public void llenaTipoPago(){
        lstTipoPago = dao.listarTipoPago();
        generarView.llenaTipoPago(lstTipoPago);
    }
    
    public void llenarTipoCorreo() {
        lstTipoCorreo = (new ClientesDAO()).listarTipoCorreo();
        generarView.llenaTipoCorreo(lstTipoCorreo);
    }
    private void llenaTipoNotaCredito() {
        lstNotaCredito = dao.listarNotaCredito(envio.getCliente());
        if (lstNotaCredito != null){
            generarView.llenaNotaCredito(lstNotaCredito);
        }        
    }
    
    public Envio GuardarEnvio(Cliente cliente, Usuario usuario, Ciudad ciudad) {
        Envio e = null;
        try {
            String receptor = generarView.getReceptor();
            String correo = generarView.getEmail();
            String esctencion =correo + dao.encontrarTipo(generarView.getTipoEmail()+1);
            receptor = receptor + "-"+esctencion;
            e = m.GuardarEnvio(cliente, usuario, generarView.getDireccion(), receptor, generarView.getPaquetes(), ciudad);     
            LogHelper.registrarOperacion(user, Constante.ACCION_REGISTRAR, Constante.OBJETO_ENVIO, "Se registró el envio con código "+e.getIdenvio());
        } catch (Exception ec) {
            ValHelper.mostrarError("No se pudo registrar el envío. Error: " + ec.getMessage());
    
        }
        return e;
    }
    
    public void SetPagoInformation(Envio envio, Usuario user) {
               
        // Obtener y Llenar datos de servicio :
        double costoUnitario = dao.ObtenerCostoUnitario(user, envio.getAeropuerto().getCiudad());
        String servicio = dao.obtenerServicio(costoUnitario);
        String origen = user.getAeropuerto().getCiudad().getDescripcion();
        generarView.llenarMensaje(servicio, origen);
        generarView.setCostoUnitario(String.valueOf(costoUnitario));
        generarView.setPaquetesFinal(String.valueOf(envio.getNumpack()));

        //Obtener y llenar datos de pago
        double total = dao.ObtenerTotal(costoUnitario, envio.getNumpack());         
        double IGV = dao.ObtenerIGV(user);    
        double subTotal = Utilitario.truncate(total*(1-IGV));
        generarView.setSubTotal(String.valueOf(subTotal));
        generarView.setIGV(String.valueOf(Utilitario.truncate(total-subTotal)));
        generarView.setTotal(String.valueOf(total));
        generarView.setFecha(new Date());
            
    }
    
    private boolean Validar() {
        boolean b = true;
        String path = generarView.getFilePath();
        if (path.isEmpty() || path.toUpperCase().trim().equals(RUTA_DOCUMENTO))
            return false;
        if (generarView.getCiudad() < 0 )
            b = false;
        if (generarView.getPaquetes().isEmpty())
            b = false;
        else if (Integer.parseInt(generarView.getPaquetes()) <= 0)
            b = false;
        return b;
    }
    
    public void mostrarPago(){
        SetPagoInformation(envio, user);
    }
    
    public void llenarGrilla(Solucion lista){
        lstVuelos = lista;
        generarView.llenaGrilla(lista);
    }
    
    public void mostrarIniciarProceso(boolean b) {
        generarView.mostrarInicioProceso(b);
    }
    
    class GenerateButtonListener implements ActionListener {
        EnviosControlador controlador;
        GenerateButtonListener(EnviosControlador c) {
            controlador = c;
        }
        
        @Override
        public void actionPerformed(ActionEvent e) {
//            JButton boton = (JButton)e.getSource();
//            boton.setCursor(boton.getCursor().getPredefinedCursor(Cursor.WAIT_CURSOR));
           
            boolean b = Validar();
            if (!b) {
                ValHelper.mostrarAlerta("Verificar datos ingresados.");
            } else  {
                generarView.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                if (Integer.parseInt(generarView.getPaquetes())>300){
                    ValHelper.mostrarAlerta("La cantidad de paquetes debe ser máximo 300.");
                } else {
                    generarView.mostrarInicioProceso(true);
    //                generarView.getPadre().repaint();
                    //Guardar Envío
                    if (envio == null){
                        envio = GuardarEnvio(cliente, user, lstCiudades.get(generarView.getCiudad()));                     
                    }
                    //Generar Solución
                    Problema problema;
                    try { //"2012-09-02 08:00:00" //"2012-11-27 01:00:00"
                        Date fechaPeticion = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse("2012-11-28 08:00:00");
                        Integer idAeropuertoOrigen = user.getAeropuerto().getIdaeropuerto();
                        Integer idAeropuertoDestino = (m.GetAeropuerto(lstCiudades.get(generarView.getCiudad()).getIdciudad())).getIdaeropuerto();
                        Integer nroPaquetes = Integer.parseInt(generarView.getPaquetes());

                        problema = new Problema(fechaPeticion, idAeropuertoOrigen, idAeropuertoDestino, nroPaquetes);       

                        lstVuelos = new MotorGeneradorTrayectoriasFachada().obtenerSolucion(problema);
                        if (lstVuelos == null) {
                            EstadoEnvio estado = new EstadoEnvio();
                            estado.setIdestado(5);
                            envio.setEstadoEnvio(estado);
                            ValHelper.mostrarAlerta("No se encontró un itinerario disponible para el envío");
                        }
                        else {
                            LogHelper.registrarOperacion(user, Constante.ACCION_GENERAR, Constante.OBJETO_ITINERARIO, "Se generó el itinerario para el envio con código "+envio.getIdenvio());
                            generarView.llenaGrilla(lstVuelos);
                            mostrarPago();
                            generarView.mostrarInicioProceso(false);
                        }
                        generarView.setEnabledCancelacion(true);
                    } catch (ParseException ex) {
                      ValHelper.mostrarError("Revisar datos iniciales. Error: " + ex.getMessage());
                    }
                    generarView.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                }
            }
        }
    }
        
    class CerrarEnvioListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
           //Actualizar estado de envio a cancelado
            if (envio == null) generarView.dispose();
            if (envio != null && envio.getIdenvio() != 0) {
                m.actualizarEnvio(envio,5);
            }
            if (lstVuelos == null && envio != null ) {
               m.actualizarEnvio(envio, 6);
            }
            generarView.dispose();
        }    
    }
    
    class CambiarLstPaisListener implements ItemListener {
        @Override
        public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange()== ItemEvent.SELECTED){
                llenarPaises(lstContinentes.get(generarView.getContinente()));
            }
        }        
    }  
    class CambiarLstCiudadListener implements ItemListener {
        @Override
        public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange()== ItemEvent.SELECTED){
                llenarCiudades(lstPais.get(generarView.getPais()));
            }
        }        
    }  
    
    class CambiarLstTipoPagoListener implements ItemListener {
        @Override
        public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange()== ItemEvent.SELECTED){
                int i = generarView.getTipoPago();
                if (i == 1){
                    generarView.enableTarjeta();
                    generarView.disableNotacredito();
                }
                else if (i==2){
                    generarView.disableTarjeta();
                    generarView.enableNotacredito();
                }
                else{
                    generarView.disableTarjeta();
                    generarView.disableNotacredito();
                }                
            }
        }        
    }  
    
    class SoloNumerosListener extends KeyAdapter {
        @Override
        public void keyTyped(KeyEvent e) {
           ValHelper.soloDigito(e);        
        }   
    }
   
    class SoloTextoListener extends KeyAdapter {
        @Override
        public void keyTyped(KeyEvent e) {
           ValHelper.soloDigitoTexto(e);
        }
    }
    
    class MostrarPagoButtonListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
  
            boolean b = true;
            Pago pago = new Pago();
            try {
                m.GenerarItinerario(envio, lstVuelos);
                TipoPago tipo = dao.ObtenerTipoPago(generarView.getTipoPago()+1);
                if (generarView.getTipoPago()==2){
                    NotaCredito nota = lstNotaCredito.get(generarView.getNotaCredito());
                    pago = dao.RegistrarPago(user, envio, tipo, nota, generarView.getTotal());
                    LogHelper.registrarOperacion(user, Constante.ACCION_REGISTRAR, Constante.OBJETO_PAGO, "Se registró el pago del envio con código "+envio.getIdenvio());
                    String nombre = envio.getCliente().getNombre() + " " + envio.getCliente().getAppaterno() + " " + envio.getCliente().getApmaterno();
                    String usuario = user.getNombre() + " " +user.getAppaterno() + " "+user.getApmaterno();
                    String correo =envio.getCliente().getCorreo()+envio.getCliente().getTipoCorreo().getExtension();
                    String receptor = envio.getReceptor();
                    String[] temp;
                    temp = receptor.split("-");                                        
                    receptor = temp[0];                    
                    String correoReceptor = temp[1];
                    EmailHelper.enviarEmailEnviosSecond(correoReceptor, receptor, usuario, envio, lstVuelos);
                    EmailHelper.enviarEmailEnviosFirst(correo, nombre, usuario, envio, lstVuelos);
                    ValHelper.mostrarAviso("El pago se registró correctamente.");
                    
                } else {
                    pago = dao.RegistrarPago(user, envio, tipo, null, generarView.getTotal());                }
                    LogHelper.registrarOperacion(user, Constante.ACCION_REGISTRAR, Constante.OBJETO_PAGO, "Se registró el pago del envio con código "+envio.getIdenvio());
                    String nombre = envio.getCliente().getNombre() + " " + envio.getCliente().getAppaterno() + " " + envio.getCliente().getApmaterno();
                    String usuario = user.getNombre() + " " +user.getAppaterno() + " "+user.getApmaterno();
                    String correo =envio.getCliente().getCorreo()+envio.getCliente().getTipoCorreo().getExtension();
                    String receptor = envio.getReceptor();
                    String[] temp;
                    temp = receptor.split("-");                                        
                    receptor = temp[0];                    
                    String correoReceptor = temp[1];
                    EmailHelper.enviarEmailEnviosFirst(correo, nombre, usuario, envio, lstVuelos);
                    EmailHelper.enviarEmailEnviosSecond(correoReceptor, receptor, usuario, envio, lstVuelos);
                    ValHelper.mostrarAviso("El pago se registró correctamente.");
                    

            } 
            catch( Exception ec ) {               
                b = false;
                ValHelper.mostrarError("No se pudo registra el pago. Error: " + ec.getMessage());
            }
            
            if (b) {
                try {
                    Ciudad destino = lstCiudades.get(generarView.getCiudad());
                    double IGV = dao.ObtenerIGV(user);
                    PdfHelper.crearPDFDocumentoPago(generarView.getFilePath()+"/SIGEPA-pago"+pago.getIdpago()+".pdf", envio, pago, user, destino, lstVuelos, IGV);
                } catch (Exception ex) {
                    b = false;
                    ValHelper.mostrarError("No se pudo generar el archivo de pago. Error: " + ex.getMessage());
                    generarView.SetBloquearCancelar();
                }
            }
            if (b)
            generarView.dispose();
        }
    }    
    
    class AbrirFile implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            JFileChooser filechooser = new JFileChooser();
            filechooser.setDialogTitle("Seleccione una carpeta");
            filechooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            int result = filechooser.showOpenDialog(null); 
            if (result == JFileChooser.APPROVE_OPTION){
               String path = filechooser.getSelectedFile().getPath();
                    generarView.setNombrePathArchivo(path);                
            }         
        }     
    }
    
    class VerRecorrido implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            MapaEnvioGUI mapa = new MapaEnvioGUI(generarView.getPadre(), true, lstVuelos);
            mapa.setVisible(true);
        }
    
    }
}
